package marcel;

/**
 * Verwaltet die Gegenstände mit Hilfe des Archivs.
 * Auflistung der Anzahl der Gegenstände (auf Lager und verliehen).
 * 
 * @author Marcel
 * @version 1.0
 * 
 */

import java.util.LinkedList;

import steffen.WSVException;

import marja.Handtuch;
import marja.KundenArchiv;
import marja.Schwimmflügel;
import marja.Surfbrett;

public class Lager 
{
	/** Speichert die Anzahl vorhandener Schwimmflügel. */
	private int anzSchwimmflügel;
	
	/** Speichert die Anzahl vorhandener Handtücher. */
	private int anzHandtücher;
	
	/** Speichert die Anzahl vorhandener Surfbretter. */
	private int anzSurfbretter;
	
	
	/** LinkedList für Handtücher, die vor 10 Uhr nicht verleihbar sind. */
	private LinkedList<Handtuch> nichtVerleihbareHandtücher = new LinkedList<Handtuch>();
	
	
	/** Festgelegter Wert des Bestandes von Schwimmflügel. */
	private final int BESTAND_SCHWIMMFLÜGEL = 61;
	
	/** Festgelegter Wert des Bestandes von Handtüchern. */
	private final int BESTAND_HANDTÜCHER = 100;
	
	/** Festgelegter Wert des Bestandes von Surfbrettern. */
	private final int BESTAND_SURFBRETTER = 10;
	
	
	/** Ruft die vorhandene Instanz des Objekts Archiv auf. */
	Archiv archiv = Archiv.getInstance();
	
	/** Erzeugt eine Instanz des Objekts Lager. */
	private static Lager lager = new Lager();
	
	/**
	 * Gibt die erzeugte Instanz des Objekts Lager zurück.
	 * 
	 * @return Lager
	 */
	public static Lager getInstance()
	{
	    return lager;
	}
	
	/** Konstruktor (setzt Anzahl der Gegenstände im Lager = Bestand). */
	private Lager()
	{
		this.anzSchwimmflügel = BESTAND_SCHWIMMFLÜGEL;
		this.anzHandtücher = BESTAND_HANDTÜCHER;
		this.anzSurfbretter = BESTAND_SURFBRETTER;
	}
	
	/**
	 * Getter zum Ausgeben der Anzahl der Schwimmflügel.
	 * 
	 * @param lager gibt an, ob die Anzahl im Lager(true) oder verliehen(false) gefragt ist
	 * @return Anzahl Schwimmflügel
	 */
	public void anzSchwimmflügelAusgeben(boolean lager)
	{
		if (lager)
		{
			System.out.println("Anzahl Schwimmflügel auf Lager: " + anzSchwimmflügel);
		}
		else
		{
			System.out.println("Anzahl verliehener Schwimmflügel: " + (BESTAND_SCHWIMMFLÜGEL-anzSchwimmflügel));
		}
	}
	
	/**
	 * Getter zum Ausgeben der Anzahl der Handtücher.
	 * Kontrolliert die verleihbaren Handtücher nach Datum jetzt.
	 * 
	 * @param lager gibt an, ob die Anzahl im Lager(true) oder verliehen(false) gefragt ist
	 * @return Anzahl Handtücher
	 */
	public void anzHandtücherAusgeben(boolean lager)
	{
		if (lager)
		{
			for (int i = 0; i < this.nichtVerleihbareHandtücher.size(); i++)
			{
				Handtuch handtuchTemp = nichtVerleihbareHandtücher.get(i);
				if (handtuchTemp.wiederVerleihbar())
				{
					this.anzHandtücher = this.anzHandtücher + handtuchTemp.getCount();
					nichtVerleihbareHandtücher.remove(i);
				}			
			}
			System.out.println("Anzahl Handtücher auf Lager: " + anzHandtücher);
		}
		else
		{
			System.out.println("Anzahl verliehener Handtücher: " + (BESTAND_HANDTÜCHER-anzHandtücher));
		}
	}
	
	/**
	 * Getter zum Ausgeben der Anzahl der Surfbretter.
	 * 
	 * @param lager gibt an, ob die Anzahl im Lager(true) oder verliehen(false) gefragt ist
	 * @return Anzahl Surfbretter
	 */
	public void anzSurfbretterAusgeben(boolean lager)
	{
		if (lager)
		{
			System.out.println("Anzahl Surfbretter auf Lager: " + this.anzSurfbretter);
		}
		else
		{
			System.out.println("Anzahl verliehener Surfbretter: " + (BESTAND_SURFBRETTER-anzSurfbretter));
		}
	}
	
	/**
	 * Minimiert die Anzahl Schwimmflügel auf Lager.
	 * Erstellt den Gegenstand mit den übergebenen Daten.
	 * Fügt den entsprechenden Gegenstand in Archiv ein.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumVon Datum des Ausleihens
	 * @param count Anzahl der Gegenstände
	 * @throws WSVException 
	 */
	public void schwimmflügelAusleihen (int kundenindex, String datumVon, int count, boolean aufblasen) throws WSVException
	{
		if (count == 0)
			throw new WSVException("Leihvorgang fehlgeschlagen! Anzahl ist gleich 0.", 17);
		if (count <= this.anzSchwimmflügel)
		{
			this.anzSchwimmflügel = this.anzSchwimmflügel - count;
			Schwimmflügel schwimmflügel = new Schwimmflügel(kundenindex, datumVon, count, aufblasen);
			archiv.fügeSchwimmflügelHinzu(schwimmflügel);
			
			System.out.println("Kunde " + KundenArchiv.getInstance().bekommeVorname(kundenindex)
								+ " " + KundenArchiv.getInstance().bekommeNachname(kundenindex)
								+ " (KdNr. " + KundenArchiv.getInstance().bekommeKundennummer(kundenindex)
								+ ") hat " + count
								+ " Schwimmflügel am " + schwimmflügel.getDatumVonString()
								+ " ausgeliehen.");
		}
		else
		{
			String Fehlermeldung = ("Leihvorgang fehlgeschlagen! Anzahl ist größer als vorhandener Bestand. Momentaner Bestand: "
										+ this.anzSchwimmflügel);
			throw new WSVException(Fehlermeldung, 18);
		}
	}
	
	/**
	 * Minimiert die Anzahl Handtücher auf Lager.
	 * Erstellt den Gegenstand mit den übergebenen Daten.
	 * Fügt den entsprechenden Gegenstand in Archiv ein.
	 * Kontrolliert die verleihbaren Handtücher nach Datum DatumVon.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumVon Datum des Ausleihens
	 * @param count Anzahl der Gegenstände
	 * @throws WSVException 
	 */
	public void handtuchAusleihen(int kundenindex, String datumVon, int count) throws WSVException
	{				
		for (int i = 0; i < this.nichtVerleihbareHandtücher.size(); i++)
		{
			Handtuch handtuchTemp = nichtVerleihbareHandtücher.get(i);
			if (handtuchTemp.wiederVerleihbar(datumVon))
			{
				this.anzHandtücher = this.anzHandtücher + handtuchTemp.getCount();
				nichtVerleihbareHandtücher.remove(i);
			}
		}
	
		if (count == 0)
			throw new WSVException("Leihvorgang fehlgeschlagen! Anzahl ist gleich 0.", 17);
		if (count <= this.anzHandtücher)
		{
			this.anzHandtücher = this.anzHandtücher - count;
			Handtuch handtuch = new Handtuch(kundenindex, datumVon, count);
			archiv.fügeHandtuchHinzu(handtuch);
			
			System.out.print("Kunde " + KundenArchiv.getInstance().bekommeVorname(kundenindex)
					+ " " + KundenArchiv.getInstance().bekommeNachname(kundenindex)
					+ " (KdNr. " + KundenArchiv.getInstance().bekommeKundennummer(kundenindex)
					+ ") hat " + count);
			if (count > 1)
				System.out.print(" Handtücher am " + handtuch.getDatumVonString());
			else
				System.out.print(" Handtuch am " + handtuch.getDatumVonString());
			System.out.println(" ausgeliehen.");
		}
		else
		{
			String Fehlermeldung = ("Leihvorgang fehlgeschlagen! Anzahl ist größer als momentaner Bestand ("
										+ this.anzHandtücher + "). Evtl. ab 10 Uhr mehr verfügbar.");
			throw new WSVException(Fehlermeldung, 19);
		}
	}
	
	
	/**
	 * Minimiert die Anzahl Surfbretter auf Lager.
	 * Erstellt den Gegenstand mit den übergebenen Daten.
	 * Fügt den entsprechenden Gegenstand in Archiv ein.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumVon Datum des Ausleihens
	 * @param count Anzahl der Gegenstände
	 * @throws WSVException 
	 */	
	public void surfbrettAusleihen(int kundenindex, String datumVon, int count) throws WSVException
	{
		if (count == 0)
			throw new WSVException("Leihvorgang fehlgeschlagen! Anzahl ist gleich 0.", 17);
		
		if (count<= this.anzSurfbretter)
		{
			this.anzSurfbretter = this.anzSurfbretter - count;
			Surfbrett surfbrett = new Surfbrett(kundenindex, datumVon, count);
			archiv.fügeSurfbrettHinzu(surfbrett);
			
			System.out.print("Kunde " + KundenArchiv.getInstance().bekommeVorname(kundenindex)
					+ " " + KundenArchiv.getInstance().bekommeNachname(kundenindex)
					+ " (KdNr. " + KundenArchiv.getInstance().bekommeKundennummer(kundenindex)
					+ ") hat " + count);
			if (count > 1)
				System.out.print(" Surfbretter am " + surfbrett.getDatumVonString());
			else
				System.out.print(" Surfbrett am " + surfbrett.getDatumVonString());
			System.out.println(" ausgeliehen.");
		}
		else
		{
			String Fehlermeldung = ("Leihvorgang fehlgeschlagen! Anzahl ist größer als vorhandener Bestand. Momentaner Bestand: "
					+ this.anzSurfbretter);
			throw new WSVException(Fehlermeldung, 20);
		}
	}
	
	/**
	 * Erhöht die Anzahl Schwimmflügel auf Lager.
	 * Fügt im Archiv das Rückgabedatum ein.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumBis Datum der Rückgabe
	 * @throws WSVException 
	 */
	public void schwimmflügelZurückgeben (int kundenindex, String datumBis) throws WSVException
	{
		int count = archiv.getCountVonSchwimmflügel(kundenindex, datumBis);
		
		this.anzSchwimmflügel = this.anzSchwimmflügel + count;
		archiv.gebeSchwimmflügelZurück(kundenindex, datumBis);
		
		System.out.print("Rückgabe ");
		if (count > 1)
			System.out.print("der Schwimmflügel ");
		else
			System.out.print("des Schwimmflügel ");				
		System.out.println("des Kunden " + KundenArchiv.getInstance().bekommeVorname(kundenindex)
				+ " " + KundenArchiv.getInstance().bekommeNachname(kundenindex)
				+ " (KdNr. " + KundenArchiv.getInstance().bekommeKundennummer(kundenindex)
				+ ") war erfolgreich.");
	}
	
	/**
	 * Packt das Handtuch in die LinkedList nichtVerleihbareHandtücher
	 * (zur späteren Datumskontrolle, da Handtuch erst ab 10 Uhr am Folgetag verleihbar).
	 * Fügt im Archiv das Rückgabedatum ein.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumBis Datum der Rückgabe
	 * @throws WSVException 
	 */
	public void handtuchZurückgeben(int kundenindex, String datumBis) throws WSVException
	{	
		LinkedList<Handtuch> nichtVerleihbareHandtücherTemp = new LinkedList<Handtuch>();
		nichtVerleihbareHandtücherTemp = archiv.gebeHandtuchZurück(kundenindex, datumBis);
		
		int count = 0;
		for(int i = 0; i < nichtVerleihbareHandtücherTemp.size(); i++)
		{
			count += nichtVerleihbareHandtücherTemp.get(i).getCount();
		}
		
		System.out.print("Rückgabe ");
		if (count > 1)
			System.out.print("der Handtücher ");
		else
			System.out.print("des Handtüches ");				
		System.out.println("des Kunden " + KundenArchiv.getInstance().bekommeVorname(kundenindex)
				+ " " + KundenArchiv.getInstance().bekommeNachname(kundenindex)
				+ " (KdNr. " + KundenArchiv.getInstance().bekommeKundennummer(kundenindex)
				+ ") war erfolgreich.");
		
		for (int i = 0; i < nichtVerleihbareHandtücherTemp.size(); i ++)
			this.nichtVerleihbareHandtücher.add(nichtVerleihbareHandtücherTemp.get(i));
	}
	
	/**
	 * Erhöht die Anzahl Surfbretter auf Lager.
	 * Fügt im Archiv das Rückgabedatum ein.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumBis Datum der Rückgabe
	 * @throws WSVException 
	 */
	public void surfbrettZurückgeben(int kundenindex, String datumBis) throws WSVException
	{
		int count = archiv.getCountVonSurfbrett(kundenindex, datumBis);
		
		this.anzSurfbretter = this.anzSurfbretter + count;
		archiv.gebeSurfbrettZurück(kundenindex, datumBis);
		
		System.out.print("Rückgabe ");
		if (count > 1)
			System.out.print("der Surfbretter ");
		else
			System.out.print("des Surfbrettes ");				
		System.out.println("des Kunden " + KundenArchiv.getInstance().bekommeVorname(kundenindex)
				+ " " + KundenArchiv.getInstance().bekommeNachname(kundenindex)
				+ " (KdNr. " + KundenArchiv.getInstance().bekommeKundennummer(kundenindex)
				+ ") war erfolgreich.");
	}
	
	/**
	 * Rechnet die Schwimmflügel bis zu einem bestimmten Datum ab.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumAbrechnen Datum, bis wohin abgerechnet werden soll
	 * @throws WSVException 
	 */
	public void schwimmflügelAbrechnen(int kundenindex, String datumAbrechnen)
	{
		archiv.rechneSchwimmflügelAb(kundenindex, datumAbrechnen);
	}
	
	/**
	 * Rechnet die Handtücher bis zu einem bestimmten Datum ab.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumAbrechnen Datum, bis wohin abgerechnet werden soll
	 * @throws WSVException 
	 */	
	public void handtuchAbrechnen(int kundenindex, String datumAbrechnen)
	{
		archiv.rechneHandtuchAb(kundenindex, datumAbrechnen);
	}
	
	/**
	 * Rechnet die Surfbretter bis zu einem bestimmten Datum ab.
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param datumAbrechnen Datum, bis wohin abgerechnet werden soll
	 * @throws WSVException 
	 */
	public void surfbrettAbrechnen(int kundenindex, String datumAbrechnen)
	{
		archiv.rechneSurfbrettAb(kundenindex, datumAbrechnen);
	}
	
	/** Auflistung der ausgeliehen Objekte, gruppiert nach Kunden. */
	public void archivAusgeben()
	{
		archiv.gebeArchivAus();
	}
	
	/**
	 * Auflistung der mit einem Kunden durchgeführten Ausleihvorgänge
	 * (offene und abgeschlossene oder nur offene).
	 * 
	 * @param kundenindex Statische Kundennummer
	 * @param AlleAusleihvorgänge Offene und Abgeschlossene bei true und offene bei false.
	 */
	public void archivAusgeben(int kundenindex, boolean AlleAusleihvorgänge)
	{
		archiv.gebeArchivAus(kundenindex, AlleAusleihvorgänge);
	}
	
	/**
	 * Auflistung der ausgeliehen Objekte nach Typ
	 * gruppiert nach Kunden und mit Leihstatus.
	 * 
	 * @param Typ Objekttyp
	 */
	public void leihstatusAusgeben(String Typ)
	{
		archiv.gebeLeihstatusAus(Typ);
		switch (Typ) 
		{
			case "Schwimmflügel":
				anzSchwimmflügelAusgeben(true);
				break;
			case "Handtuch":
				anzHandtücherAusgeben(true);
				break;
			case "Surfbrett":
				anzSurfbretterAusgeben(true);
				break;
	
			default:
				break;
		}
	}
	
	/**
	 * Auflistung aller Objekte
	 * gruppiert nach Objekte und mit Leihstatus.
	 */
	public void leihstatusAusgeben()
	{
		archiv.gebeLeihstatusAus("Handtuch");
		anzHandtücherAusgeben(true);
		System.out.println();
		System.out.println();
		
		archiv.gebeLeihstatusAus("Schwimmflügel");
		anzSchwimmflügelAusgeben(true);
		System.out.println();
		System.out.println();
		
		archiv.gebeLeihstatusAus("Surfbrett");
		anzSurfbretterAusgeben(true);
		System.out.println();
		System.out.println();
	}
}
